import pandas as pd
import os
from typing import List
import numpy as np
# 计算收敛阶


def create_file(filename="convergence_rate.xlsx"):
    """
    传入文件名
    设置表头
    """
    if os.path.exists(filename):
        print(f"{filename}已存在.")
    else:
        # 创建file.xlsx
        df = pd.DataFrame(columns=["N", "H1(vel)", "H1(vel)-rate", "H1(press)", "H1(press)-rate", "L2(vel)",
                                   "L2(vel)-rate", "L2(press)", "L2(press)-rate", "Linf(vel)", "Linf(vel)-rate", "Linf(press)", "Linf(press)-rate"])
        # 将DataFrame写入Excel文件
        df.to_excel(filename, index=False)


def save_data(filename="convergence_rate.xlsx", data: List[float] = None):
    """
    传入文件名和数据
    将数据写入文件
    """
    assert os.path.exists(filename), "表头文件不存在"
    assert len(data) == 7, "data长度不正确"
    N, h1_vel, h1_press, l2_vel,  l2_press,  linf_vel,  linf_press = data
    df = pd.read_excel(filename)
    new_row = pd.Series(
        [N, h1_vel, None, h1_press, None, l2_vel, None, l2_press, None, linf_vel, None, linf_press,
         None], index=df.columns)
    df = pd.concat([df, new_row.to_frame().T], ignore_index=True)
    df.to_excel(filename, index=False)
    

def get_convergence_order(filename="convergence_rate.xlsx", ratio=2):
    """
    默认网格剖分翻倍
    """
    assert os.path.exists(filename), "表头文件不存在"
    df = pd.read_excel(filename)
    # 读取数据
    N = df["N"].values
    h1_vel = df["H1(vel)"].values
    h1_press = df["H1(press)"].values
    l2_vel = df["L2(vel)"].values
    l2_press = df["L2(press)"].values
    linf_vel = df["Linf(vel)"].values
    linf_press = df["Linf(press)"].values
    # calc
    h1_vel_rate = calc_convergence_order(N, h1_vel)
    h1_press_rate = calc_convergence_order(N, h1_press)
    l2_vel_rate = calc_convergence_order(N, l2_vel)
    l2_press_rate = calc_convergence_order(N, l2_press)
    linf_vel_rate = calc_convergence_order(N, linf_vel)
    linf_press_rate = calc_convergence_order(N, linf_press)
    # 将结果写入文件
    df["H1(vel)-rate"] = h1_vel_rate
    df["H1(press)-rate"] = h1_press_rate
    df["L2(vel)-rate"] = l2_vel_rate
    df["L2(press)-rate"] = l2_press_rate
    df["Linf(vel)-rate"] = linf_vel_rate
    df["Linf(press)-rate"] = linf_press_rate
    df.to_excel(filename, index=False)
    
    print(f"收敛阶计算完成,结果已写入{filename}")
    

def calc_convergence_order(N: np.ndarray, arr1: np.ndarray, ratio=2):
    """
    默认翻倍剖分
    N为网格剖分列表 元素必须是数字
    例如[4, 8, 16] 不可以是[[4, 1], [8, 2], [16, 4]]
    arr1为误差列表
    """
    assert len(N) == len(arr1) and len(N) > 1, "N和arr1长度需一致 且 长度大于1"
    res = np.zeros(len(N))
    res[0] = np.nan
    if ratio == 2:
        res[1:] =  -np.log10(arr1[1:] / arr1[:-1]) / np.log10(2)
    else:
        res[1:] = -np.log10(arr1[1:] / arr1[:-1]) / np.log10(N[1:] / N[:-1])
    return res
    

# Test Code
# create_file("convergence_rate.xlsx")
# test1 = [[4, 1], 0.1, 0.2, 0.3, 1e-5, 0.5, 0.6]
# test2 = [[8, 2], 0.2, 0.4, 0.4, (1e-5)/2, 0.6, 0.7]
# test3 = [[16, 4], 0.4, 0.8, 0.5, (1e-5)/4, 0.7, 0.8]
# save_data("convergence_rate.xlsx", test1)
# save_data("convergence_rate.xlsx", test2)
# save_data("convergence_rate.xlsx", test3)
# get_convergence_order("convergence_rate.xlsx")

